package code.homework;

import java.util.*;

/**
 * @author cc
 * @create 2023-01-17  22:34
 */
public class NextLargerElement {
    /**
     * nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。
     *
     * 给你两个 没有重复元素 的数组 nums1 和 nums2 ，下标从 0 开始计数，其中nums1 是 nums2 的子集。
     *
     * 对于每个 0 <= i < nums1.length ，找出满足 nums1[i] == nums2[j] 的下标 j ，并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素，那么本次查询的答案是 -1 。
     *
     * 返回一个长度为 nums1.length 的数组 ans 作为答案，满足 ans[i] 是如上所述的 下一个更大元素 。
     *
     *  
     *
     * 示例 1：
     *
     * 输入：nums1 = [4,1,2], nums2 = [1,3,4,2].
     * 输出：[-1,3,-1]
     * 解释：nums1 中每个值的下一个更大元素如下所述：
     * - 4 ，用加粗斜体标识，nums2 = [1,3,4,2]。不存在下一个更大元素，所以答案是 -1 。
     * - 1 ，用加粗斜体标识，nums2 = [1,3,4,2]。下一个更大元素是 3 。
     * - 2 ，用加粗斜体标识，nums2 = [1,3,4,2]。不存在下一个更大元素，所以答案是 -1 。
     * 示例 2：
     *
     * 输入：nums1 = [2,4], nums2 = [1,2,3,4].
     * 输出：[3,-1]
     * 解释：nums1 中每个值的下一个更大元素如下所述：
     * - 2 ，用加粗斜体标识，nums2 = [1,2,3,4]。下一个更大元素是 3 。
     * - 4 ，用加粗斜体标识，nums2 = [1,2,3,4]。不存在下一个更大元素，所以答案是 -1 。
     *  
     *
     * 提示：
     *
     * 1 <= nums1.length <= nums2.length <= 1000
     * 0 <= nums1[i], nums2[i] <= 104
     * nums1和nums2中所有整数 互不相同
     * nums1 中的所有整数同样出现在 nums2 中
     *
     * 来源：力扣（LeetCode）
     * 链接：https://leetcode.cn/problems/next-greater-element-i
     * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
     */


    /**
     * 1,3,2,4
     * 栈：[1]  Map：{}
     * 栈：[3]  Map：{1：3}
     * 栈：[2，3]  Map：{1：3}
     * 栈：[4]  Map：{1：3，2：4，3：4}
     */
    public int[] nextGreaterElementA(int[] nums1, int[] nums2) {
        int[] result = new int[nums1.length];
        Map<Integer, Integer> map = new HashMap<>();
        /**
         * 　　add        增加一个元索                  如果队列已满，则抛出一个IIIegaISlabEepeplian异常
         * 　　remove     移除并返回队列头部的元素       如果队列为空，则抛出一个NoSuchElementException异常
         * 　　element    返回队列头部的元素            如果队列为空，则抛出一个NoSuchElementException异常
         * 　　offer      添加一个元素并返回true        如果队列已满，则返回false
         * 　　poll       移除并返问队列头部的元素      如果队列为空，则返回null
         * 　　peek       返回队列头部的元素            如果队列为空，则返回null
         * 　　put        添加一个元素                  如果队列满，则阻塞
         * 　　take       移除并返回队列头部的元素       如果队列为空，则阻塞
         *     push       添加一个元素到头部 =addFirst  如果队列已满，则抛出一个IIIegaISlabEepeplian异常
         */


        Deque<Integer> stack = new ArrayDeque<>();
        for (int i : nums2) {
            Integer peek;
            while ((peek = stack.peek()) != null && peek < i) {
                map.put(stack.poll(), i);
            }
            stack.push(i);
        }

        for (int j = 0; j < nums1.length; j++) {
            result[j] = map.containsKey(nums1[j]) ? map.get(nums1[j]) : -1;
        }
        return result;
    }

    public int[] nextGreaterElementB(int[] nums1, int[] nums2) {
        int[] result = new int[nums1.length];
        Map<Integer, Integer> map = new HashMap<>();

        Stack<Integer> stack = new Stack<>();
        for (int i : nums2) {
            while (!stack.isEmpty() && (stack.peek()) < i) {
                map.put(stack.pop(), i);
            }
            stack.push(i);
        }

        for (int j = 0; j < nums1.length; j++) {
            result[j] = map.containsKey(nums1[j]) ? map.get(nums1[j]) : -1;
        }
        return result;
    }


}
